#!/usr/bin/python
# -*- coding: utf-8 -*-

#This file is part of pyLot library.
#
# pyLot is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# pyLot is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with pyLot.  If not, see <http://www.gnu.org/licenses/>.

__author__ = u'Pierre Puiseux, Guillaume Baty'
__copyright__ = u"Copyright 2011-2012 (C) andheo, Université de Pau et des Pays de l'Adour"
__credits__ = [u'Pierre Puiseux', u'Guillaume Baty']
__license__ = "GNU Lesser General Public License"

u"""
pyLot widget interface.
  - 03-2010, Pierre Puiseux, Guillaume Baty
  
Université de Pau et des Pays de l'Adour, INRIA
"""

__all__ = [u'IWidget']

from Qt4 import QtGui

from traits.api import List, Unicode, Str, Instance, Python

from pyLot.core import IBaseHandler, IHandler
from ..interfaces.i_basewidget import IBaseWidget

class IWidget(IBaseWidget, IBaseHandler):
  u"""

  Un widget pyLot peut proposer ... 
    - des menus (widgets.menus)
    - des tool bars (widget.tool_bars)
    - un editeur de preferences (:meth:`getPreferences`)
    - des docks (widgets.docks)
  
  Un widget pyLot doit **obligatoirement** être associé à un handler (IHandler) 
  qui s'occupe du traitement des données.
  
  Ce widget défini un certain nombre de méthode qui sont généralement utilisées 
  par les classes parentes et les fenêtres principales.
  Ces méthodes sont appelés dans un ordre précis :
    appel/installation des méthodes globales (niveau pylot)
    appel des méthodes des enfants (car ceux-ci sont 100% indépendant)
    appel des méthodes des pref si dispo
    appel de la méthode locale au widget (car le widget peut dépendre de l'état
    de ses enfants)
  """

  def _setpref(self, preferences):
    """
    pref setter
    """

  def _gethandler(self):
    u"""The handler to which are delegated all works.
    :returns: the handler.
    :rtype: :class:`~_pylot.interfaces.HandlerInterface`
    """

  u"""Human readable name. This string may be translated or changed so do not
  use it as reference or input but only for display purposes.
  For example, for a simple calculator with identifier 
  "pyLot.widget.calculator" you can use alias "Simple Calculator" """
  alias = Unicode
  u"""Unique identifier. You should use convention "module.interface.name" 
  For example 'pyLot.widget.calculator' """
  identifier = Str

  u"""the handler to which are delegated all works."""
  handler = Instance(IHandler)

  u"""
  return associated menus (List of QMenu objects).
  """
  menus = List
  pref = Python
  u"""
  return associated toolbars (List of QToolBar objects).
  """
  tool_bars = List
  u"""
  return associated dockable widgets.
  (List of QWidget instance and not QDockWidgets nor classes !)
  """
  docks = List

  def __iter__(self):
    u"""
    returns all child widget implementing IWidget.
    This iterator is generally used by all recursive methods.
    It is the equivalent to QWidget.children() method but returns only widgets
    implementing IWidget interface.
    """

  def init(self):
    u"""
    Use this method to finish widget initialization, 
    once all widgets are created. This method call init method of child
    widget recursively. 
    
    For example, you can call child init methods using :
    
    QtGui.QTimer.singleShot(0, child.init)
  
    """

  def readyToClose(self):
    u"""
    Call readyToClose method recursively (see __iter__). If result is True, You can close all 
    child widgets. 
    Closing is done in two steps (readyToClose, then close) to avoid partial close.
    For example, if structure is
    
    MainWidget
      |-> widget1
      |-> widget2
      
    You call MainWidget.close().
    widget1.close() is called, widget1 is deleted
    widget2.close() is called, widget2 catch closeEvent and ignore it (quit canceled by user for example)
    closeEvent stops and results in a widget partially closed.
    
    Using readyToClose approach solve this problem.
    First, you can test all children with readyToClose(). If answer is True,
    all widgets can be closed. You can call close() recursively.
    
    Settings (Window state for example) are generally saved between 
    readyToClose and close. This is not handled in this interface.
    
    Default must return True
    """

  def switchUserLevel(self, level=None, force=False, recursive=True):
    u"""
    Switches display level.
    This method calls recursively (see __iter__) switchUserLevel method of 
    all children's widgets and preferences.

    If level is not defined, it uses handler level.

    .. warning ::
      
      You must call "handler.switchUserLevel" method
      (in general before instructions)

    """

  def fineTune(self, recursive=True):
    u"""
    Last cosmetic touch
    """

if  __name__ == u"__main__":
  pass
